#include "stdafx.h"
#include "PlayDialog.h"
#include "resource.h"
#include "StrCodeUtil.h"
#include "NotifyLibFuncErrorUtil.h"

PlayDialog::PlayDialog(void)
    : m_hDlg(NULL)
    , m_bIsPlaying(false)
    , m_chanId(-1)
#if DD_USING_SA_VOE_WAPPER
    , m_pVoeWarpper(nullptr)
#endif //DD_USING_SA_VOE_WAPPER
{
}


PlayDialog::~PlayDialog(void)
{
    unInit();
}


void PlayDialog::init(HWND hDlg)
{
    m_hDlg = hDlg;

#if DD_USING_SA_VOE_WAPPER
    int iLibRev = 0;
    m_pVoeWarpper = NS_SA::SaVoeWrapper::GetInstance();
    if (!m_pVoeWarpper || (iLibRev = m_pVoeWarpper->Init()) || 0 != iLibRev)
    {
        NotifyLibFuncErrorUtil::NotifyFuncError(m_hDlg, "init", iLibRev);
    }

    // play dev
    {
        int iPlayDevNum = m_pVoeWarpper->PlayoutDevicesNum();
        if (iPlayDevNum <= 0)
        {
            SendDlgItemMessage(m_hDlg, IDC_COMBO_PLAY_DEV, (UINT)CB_ADDSTRING, (WPARAM)0, (LPARAM)TEXT("None"));
        }
        else
        {
            char bufUtf8Name[1024];
            std::string strUtf8Name("");
            for (int i = 0; i < iPlayDevNum; i++)
            {
                memset(bufUtf8Name, 0x00, sizeof(bufUtf8Name));
                m_pVoeWarpper->PlayoutDeviceName(i, bufUtf8Name, sizeof(bufUtf8Name));

                // to wstring
                strUtf8Name = bufUtf8Name;
                std::wstring strName = StrCodeUtil::utf8_decode(strUtf8Name);
                SendDlgItemMessage(m_hDlg, IDC_COMBO_PLAY_DEV, (UINT)CB_ADDSTRING, (WPARAM)0, (LPARAM)strName.c_str());
            }

            // defalut select
            SendDlgItemMessage(m_hDlg, IDC_COMBO_PLAY_DEV, (UINT)CB_SETCURSEL, (WPARAM)0, (LPARAM)0);
        }
    }

    // play format
    {
        int iPlayFormatNum = m_pVoeWarpper->SupportPlayLocalFileFormatNum();
        if (iPlayFormatNum <= 0)
        {
            SendDlgItemMessage(m_hDlg, IDC_COMBO_PLAY_FORMAT, (UINT) CB_ADDSTRING,(WPARAM) 0,(LPARAM) TEXT("None"));
        }
        else
        {
            char bufUtf8Disp[1024];
            std::string strUtf8Disp("");
            for (int i = 0; i < iPlayFormatNum; i++)
            {
                memset(bufUtf8Disp, 0x00, sizeof(bufUtf8Disp));
                m_pVoeWarpper->SupportPlayLocalFileFormatDisp(i, bufUtf8Disp, sizeof(bufUtf8Disp));

                // to wstring
                strUtf8Disp = bufUtf8Disp;
                std::wstring strDisp = StrCodeUtil::utf8_decode(strUtf8Disp);
                SendDlgItemMessage(m_hDlg, IDC_COMBO_PLAY_FORMAT, (UINT)CB_ADDSTRING, (WPARAM)0, (LPARAM)strDisp.c_str());
            }

            // defalut select
            SendDlgItemMessage(m_hDlg, IDC_COMBO_PLAY_FORMAT, (UINT)CB_SETCURSEL, (WPARAM)0, (LPARAM)0);
        }
    }
#else
    voe_init("./logWebRtcPlay.log", webrtc::kTraceError | webrtc::kTraceDebug | webrtc::kTraceInfo | webrtc::kTraceWarning, webrtc::kTraceModuleAll);
    voe_set_log_path("logWebRtcPlay.log");

    // play dev
    {
        int iPlayDevNum = 0;
        voe_get_play_device_count(iPlayDevNum);
        if (iPlayDevNum <= 0)
        {
            SendDlgItemMessage(m_hDlg, IDC_COMBO_PLAY_DEV, (UINT)CB_ADDSTRING, (WPARAM)0, (LPARAM)TEXT("None"));
        }
        else
        {
            char strNameUTF8[128];
            char strGuidUTF8[128];
            for (int i = 0; i < iPlayDevNum; i++)
            {
                memset(strNameUTF8, 0x00, sizeof(strNameUTF8));
                memset(strGuidUTF8, 0x00, sizeof(strGuidUTF8));
                voe_get_play_device_name(i, strNameUTF8, strGuidUTF8);

                // to wstring
                std::string strUtf8Name(strNameUTF8);
                std::wstring strName = StrCodeUtil::utf8_decode(strUtf8Name);
                SendDlgItemMessage(m_hDlg, IDC_COMBO_PLAY_DEV, (UINT)CB_ADDSTRING, (WPARAM)0, (LPARAM)strName.c_str());
            }

            // defalut select
            SendDlgItemMessage(m_hDlg, IDC_COMBO_PLAY_DEV, (UINT)CB_SETCURSEL, (WPARAM)0, (LPARAM)0);
        }
    }

    // play format
    {
        int iPlayFormatNum = voe_get_play_local_file_format_count();
        if (iPlayFormatNum <= 0)
        {
            SendDlgItemMessage(m_hDlg, IDC_COMBO_PLAY_FORMAT, (UINT)CB_ADDSTRING, (WPARAM)0, (LPARAM)TEXT("None"));
        }
        else
        {
            char strUtf8Disp[1024];
            for (int i = 0; i < iPlayFormatNum; i++)
            {
                memset(strUtf8Disp, 0x00, sizeof(strUtf8Disp));
                voe_get_play_local_file_format_name(i, strUtf8Disp);

                // to wstring
                std::wstring strDisp = StrCodeUtil::utf8_decode(strUtf8Disp);
                SendDlgItemMessage(m_hDlg, IDC_COMBO_PLAY_FORMAT, (UINT)CB_ADDSTRING, (WPARAM)0, (LPARAM)strDisp.c_str());
            }

            // defalut select
            SendDlgItemMessage(m_hDlg, IDC_COMBO_PLAY_FORMAT, (UINT)CB_SETCURSEL, (WPARAM)0, (LPARAM)0);
        }
    }

    m_chanId = voe_create_channel();

    if(m_chanId >= 0)
    {
        voe_channel_enable_packet_separate(m_chanId, true);
        voe_channel_start_receive(m_chanId);
        voe_channel_start_playout(m_chanId);
    }
#endif //DD_USING_SA_VOE_WAPPER
}


void PlayDialog::unInit()
{
#if DD_USING_SA_VOE_WAPPER
    NS_SA::SaVoeWrapper::Destory();
    m_pVoeWarpper = nullptr;
    m_bIsPlaying = false;
#else
    if (m_chanId >= 0)
    {
        voe_channel_stop_receive(m_chanId);
        voe_channel_stop_playout(m_chanId);
        voe_delete_channel(m_chanId);
        m_chanId = -1;
        m_bIsPlaying = false;
    }

    voe_release();
#endif //DD_USING_SA_VOE_WAPPER
}


void PlayDialog::startPlay()
{
    // get dev channel
    int iDevIdx = SendDlgItemMessage(m_hDlg, IDC_COMBO_PLAY_DEV, (UINT)CB_GETCURSEL, (WPARAM)0, (LPARAM)0);

    // get play format index
    int iPlayFormatIdx = SendDlgItemMessage(m_hDlg, IDC_COMBO_PLAY_FORMAT, (UINT)CB_GETCURSEL, (WPARAM)0, (LPARAM)0);

    // get input file name
    int iCharNum = SendDlgItemMessage(m_hDlg, IDC_EDIT_PATH, (UINT)WM_GETTEXTLENGTH, (WPARAM)0, (LPARAM)0);
    iCharNum++;
    TCHAR* pWstrBuf = new TCHAR[iCharNum];
    SendDlgItemMessage(m_hDlg, IDC_EDIT_PATH, (UINT)WM_GETTEXT, (WPARAM)iCharNum, (LPARAM)pWstrBuf);
    std::wstring wstrPath(pWstrBuf);
    std::string strPath = StrCodeUtil::utf8_encode(wstrPath);
    delete pWstrBuf;

#if DD_USING_SA_VOE_WAPPER
    int iLibRev = 0;
    iLibRev = m_pVoeWarpper->SetPlayLocalFileFormat(iPlayFormatIdx);
    if (0 != iLibRev)
    {
        NotifyLibFuncErrorUtil::NotifyFuncError(m_hDlg, "SetPlayLocalFileFormat", iLibRev);
    }

    iLibRev = m_pVoeWarpper->SetPlayoutDevice(iDevIdx); 
    if (0 != iLibRev)
    {
        NotifyLibFuncErrorUtil::NotifyFuncError(m_hDlg, "SetPlayoutDevice", iLibRev);
    }

    iLibRev = m_pVoeWarpper->StartPlayingFileLocally(strPath.c_str());
    if (0 != iLibRev)
    {
        NotifyLibFuncErrorUtil::NotifyFuncError(m_hDlg, "StartPlayingFileLocally", iLibRev);
    }
#else
    // play format
    if (0 != voe_set_play_local_file_format(iPlayFormatIdx))
    {
        MessageBox(m_hDlg, TEXT("voe_set_play_local_file_format failed"), TEXT("webrtc error"), MB_OK);
        return;
    }

    // play
    if (0 != voe_set_play_device(iDevIdx))
    {
        MessageBox(m_hDlg, TEXT("voe_set_play_device failed"), TEXT("webrtc error"), MB_OK);
        return;
    }

    // aec
    bool bIsEnableAec = (BST_CHECKED == SendDlgItemMessage(m_hDlg, IDC_CHECK_CHECK_AEC, (UINT)BM_GETCHECK, (WPARAM)0, (LPARAM)0));
    if (bIsEnableAec)
    {
        voe_set_ec_mode(true, webrtc::kEcAec);
        voe_set_aecm_mode(false, 3);
    }
    else
    {
        voe_set_ec_mode(false, webrtc::kEcAec);
        voe_set_aecm_mode(true, 3);
    }

    if(m_chanId >= 0)
    {
        voe_channel_enable_packet_separate(m_chanId, true);
        voe_channel_start_receive(m_chanId);
        voe_channel_start_playout(m_chanId);
    }
    if (0 != voe_channel_start_play_file_locally(m_chanId, strPath.c_str(), true))
    {
        MessageBox(m_hDlg, TEXT("voe_channel_start_play_file_locally failed"), TEXT("webrtc error"), MB_OK);
        return;
    }
#endif //DD_USING_SA_VOE_WAPPER

    // record
    m_bIsPlaying = true;
}


void PlayDialog::stopPlay()
{
    if (m_bIsPlaying)
    {
        #if DD_USING_SA_VOE_WAPPER
        int iLibRev = m_pVoeWarpper->StopPlayingFileLocally(); 
        if (0 != iLibRev)
        {
            NotifyLibFuncErrorUtil::NotifyFuncError(m_hDlg, "StopPlayingFileLocally", iLibRev);
        }

        #else
        if (m_chanId >= 0)
        {
            voe_channel_stop_play_file_locally(m_chanId);
            voe_channel_stop_receive(m_chanId);
            voe_channel_stop_playout(m_chanId);
        }
        #endif //DD_USING_SA_VOE_WAPPER
        // record
        m_bIsPlaying = false;
    }
}


bool PlayDialog::isPlaying(void) const
{
    return m_bIsPlaying;
}